package com.jcfk.eam.service.mould;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.jcfk.common.business.service.BaseService;
import com.jcfk.common.core.context.ApplicationContextHolder;
import com.jcfk.common.core.exception.CustomException;
import com.jcfk.common.core.utils.BeanUtils;
import com.jcfk.common.core.utils.IdUtils;
import com.jcfk.common.security.constant.SecurityConstants;
import com.jcfk.common.security.service.TokenService;
import com.jcfk.common.security.utils.SecurityUtils;
import com.jcfk.common.web.domain.DataPage;
import com.jcfk.common.web.domain.LoginInfo;
import com.jcfk.common.web.domain.RetResult;
import com.jcfk.eam.api.SysServiceFeign;
import com.jcfk.eam.api.dto.SysUserWithRoleIdDTO;
import com.jcfk.eam.dao.mould.EamMouldEmailRecordDao;
import com.jcfk.eam.domain.dto.mould.EamMouldEmailRecordDTO;
import com.jcfk.eam.domain.dto.mould.EamMouldEmailRecordDetailDTO;
import com.jcfk.eam.domain.dto.mould.EamMouldEmailRecordFileDTO;
import com.jcfk.eam.domain.po.main.EamAssetInfo;
import com.jcfk.eam.domain.po.mould.EamAssetMouldProduct;
import com.jcfk.eam.domain.po.mould.EamMouldEmailConfig;
import com.jcfk.eam.domain.po.mould.EamMouldEmailRecord;
import com.jcfk.eam.domain.po.mould.EamMouldEmailRecordDetail;
import com.jcfk.eam.domain.query.mould.EamMouldEmailRecordFileQuery;
import com.jcfk.eam.domain.query.mould.EamMouldEmailRecordQuery;
import com.jcfk.eam.service.main.EamAssetInfoService;
import com.jcfk.system.api.ifeign.SysMessageCenterServiceFeign;
import com.jcfk.system.domain.dto.SysUserDTO;
import com.jcfk.system.domain.model.SendMsgModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

import static com.jcfk.common.core.utils.BeanUtils.convertList;

/**
 * 模具寿命邮件发送记录主表
 *
 * @author yrl
 * @email
 * @date 2025-07-28
 */
@Service
public class EamMouldEmailRecordService extends BaseService<EamMouldEmailRecordDao, EamMouldEmailRecord> {


    @Autowired
    private EamMouldEmailRecordDetailService eamMouldEmailRecordDetailService;
    @Autowired
    private EamAssetInfoService eamAssetInfoService;
    @Autowired
    private EamMouldEmailConfigService eamMouldEmailConfigService;
    @Autowired
    private SysServiceFeign sysServiceFeign;
    @Resource
    private SysMessageCenterServiceFeign sysMessageCenterServiceFeign;
    @Autowired
    private EamAssetMouldProductService eamAssetMouldProductService;
    @Autowired
    private EamMouldEmailRecordFileService eamMouldEmailRecordFileService;
    @Autowired
    private TokenService tokenService;

    @Value("${xxl.job.executor.userId}")
    private String userId;

    @Value("${xxl.job.executor.userName}")
    private String userName;

    @Value("${xxl.job.executor.loginUserName}")
    private String loginUserName;

    @Value("${xxl.job.executor.empNo}")
    private String empNo;

    /**
     * EamMouldEmailRecord分页查询
     *
     * @param page  分页设置
     * @param query 查询条件
     * @return 分页查询结果
     */
    public DataPage<EamMouldEmailRecordDTO> queryByPage(DataPage<EamMouldEmailRecordDTO> page, EamMouldEmailRecordQuery query) {
        // 分页查询
        page = this.baseMapper.queryByPage(page, query);
        return page;
    }

    /**
     * 根据条件获取单表信息列表
     *
     * @param query 查询条件
     * @return List<EamMouldEmailRecordDTO>
     */
    public List<EamMouldEmailRecordDTO> getList(EamMouldEmailRecordQuery query) {
        // 查询条件
        QueryWrapper<EamMouldEmailRecord> qw = new QueryWrapper<>();
        qw.lambda().eq(!StrUtil.isEmpty(query.getAssetId()), EamMouldEmailRecord::getAssetId, query.getAssetId());
        qw.lambda().eq(!StrUtil.isEmpty(query.getLocationId()), EamMouldEmailRecord::getLocationId, query.getLocationId());
        qw.lambda().eq(!StrUtil.isEmpty(query.getAssetTypeId()), EamMouldEmailRecord::getAssetTypeId, query.getAssetTypeId());
        qw.lambda().ge(!StrUtil.isEmpty(query.getRegistrationTimeStart()), EamMouldEmailRecord::getRegistrationTime, query.getRegistrationTimeStart());
        qw.lambda().le(!StrUtil.isEmpty(query.getRegistrationTimeEnd()), EamMouldEmailRecord::getRegistrationTime, query.getRegistrationTimeEnd());
        // 查询数据
        List<EamMouldEmailRecord> list = super.list(qw);

        return convertList(list, EamMouldEmailRecordDTO.class);
    }

    /**
     * 获取根据关联id详情表列表
     *
     * @param query 查询条件
     * @return List<EamMouldEmailRecordDTO>
     */
    public List<EamMouldEmailRecordDetailDTO> getDetails(EamMouldEmailRecordQuery query) {
        // 查询条件
        QueryWrapper<EamMouldEmailRecordDetail> qw = new QueryWrapper<>();
        qw.lambda().eq(!StrUtil.isEmpty(query.getId()), EamMouldEmailRecordDetail::getRecordId, query.getId());

        // 查询数据
        List<EamMouldEmailRecordDetail> list = eamMouldEmailRecordDetailService.list(qw);

        return convertList(list, EamMouldEmailRecordDetailDTO.class);
    }


    /**
     * 判断EamMouldEmailRecord是已经存在
     *
     * @param dto
     * @return
     */
    public RetResult<String> isValid(EamMouldEmailRecordDTO dto) {
        QueryWrapper<EamMouldEmailRecord> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("deleted", 0);
        return RetResult.ok();
    }

    /**
     * 插入模具寿命邮件发送记录主表
     *
     * @param dto 插入对象
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public void insert(EamMouldEmailRecordDTO dto) {

        // 保存
        EamMouldEmailRecord item = new EamMouldEmailRecord();
        BeanUtils.copyProperties(dto, item);
        this.setDefaultValue(item);

        super.save(item);

        // 保存明细表
        eamMouldEmailRecordDetailService.saveBatch(dto.getDetails(), item.getId());
    }


    /**
     * 更新模具寿命邮件发送记录主表
     *
     * @param dto 更新对象
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public void update(EamMouldEmailRecordDTO dto) {

        // 保存
        EamMouldEmailRecord item = new EamMouldEmailRecord();
        BeanUtils.copyProperties(dto, item);

        // 默认数据
        this.setDefaultValue(item);

        super.updateById(item);
        // 保存明细表
        if (dto.getDetails() != null) {
            eamMouldEmailRecordDetailService.saveBatch(dto.getDetails(), item.getId());
        }
        if (dto.getFiles() != null) {
            eamMouldEmailRecordFileService.saveFileBatch(dto.getFiles(), item.getId());
        }
    }


    /**
     * 根据批量主键删除模具寿命邮件发送记录主表(逻辑删除)
     *
     * @param dto
     * @return bool
     */
    @Transactional(rollbackFor = Exception.class)
    public Boolean logicDeleteList(EamMouldEmailRecordDTO dto) {

        EamMouldEmailRecord item = new EamMouldEmailRecord();

        this.setDefaultValue(item);
        item.setDeleted(1);

        QueryWrapper<EamMouldEmailRecord> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("id", dto.getIds());

        return this.update(item, queryWrapper);
    }

    /**
     * 设置添加默认值
     *
     * @param item 添加对象
     */
    public void setDefaultValue(EamMouldEmailRecord item) {
        if (StrUtil.isEmpty(item.getCreatedUserId())) {
            item.setCreatedUserId(SecurityUtils.getUserId());
            item.setCreateTime(new Date());
            item.setDeleted(0);
            item.setCreatedUserName(SecurityUtils.getUserName());
        }
        item.setLastUpdatedUserId(SecurityUtils.getUserId());
        item.setLastUpdateTime(new Date());

        item.setLastUpdatedUserName(SecurityUtils.getUserName());
    }


    /**
     * 根据主键获取模具寿命邮件发送记录主表信息
     *
     * @param id 主键
     * @return StandardCodeDTO
     */
    public EamMouldEmailRecordDTO get(String id) {
        // 查询数据
        EamMouldEmailRecord item = this.baseMapper.selectById(id);
        EamMouldEmailRecordDTO dto = new EamMouldEmailRecordDTO();
        try {
            BeanUtils.copyProperties(item, dto);
        } catch (RuntimeException e) {
            throw e;
        }

        return dto;
    }


    /**
     * 根据主键获取模具寿命邮件发送记录主表信息
     *
     * @param id 主键
     * @return StandardCodeDTO
     */
    public void deleteItem(String id) {
        EamMouldEmailRecord item = getById(id);
        this.setDefaultValue(item);
        item.setDeleted(1);

        this.updateById(item);
    }


    //    @Scheduled(cron = "0 * * * * ?")
    @Transactional(rollbackFor = Exception.class)
    public void checkMouldLife() {
        // 查询邮件配置
        List<EamMouldEmailConfig> configList = eamMouldEmailConfigService.list(Wrappers.<EamMouldEmailConfig>lambdaQuery()
                .eq(EamMouldEmailConfig::getEnabled, 1)
                .eq(EamMouldEmailConfig::getDeleted, 0));
        if (CollUtil.isEmpty(configList)) return;
        Map<String, List<EamMouldEmailConfig>> configMap = configList.stream().collect(Collectors.groupingBy(EamMouldEmailConfig::getProductId));
        List<String> productIds = configList.stream().map(EamMouldEmailConfig::getProductId).collect(Collectors.toList());
        if (CollUtil.isEmpty(productIds)) return;
        // 查询配置下的指定模具
        List<EamAssetMouldProduct> productList = eamAssetMouldProductService.list(Wrappers.<EamAssetMouldProduct>lambdaQuery()
                .in(EamAssetMouldProduct::getProductId, productIds));
        if (CollUtil.isEmpty(productList)) return;

        List<EamAssetInfo> mouldList = eamAssetInfoService.getMouldListByProduct(productIds);
//        List<EamAssetInfo> mouldList = eamAssetInfoService.getMouldListByProduct(Wrappers.<EamAssetInfo>lambdaQuery()
//            .in(EamAssetInfo::getId, productList.stream().map(EamAssetMouldProduct::getAssetId).collect(Collectors.toList()))
//            .eq(EamAssetInfo::getDeleted, 0)
//            .eq(EamAssetInfo::getAssetKind, 3)
//            // 待确认  都什么状态的模具需要发消息
        // 确认 所有状态都发送邮件
//            .in(EamAssetInfo::getAssetStatus, 1, 3, 4, 7)
//        );
        if (CollUtil.isEmpty(mouldList)) return;
        // 查询配置下的指定模具的邮件发送记录<模具主键+阶段, 发送记录>
        Map<String, EamMouldEmailRecord> existRecord = new HashMap<>();
        if (CollUtil.isNotEmpty(mouldList)) {
            List<String> mouldIdList = mouldList.stream().map(EamAssetInfo::getId).distinct().collect(Collectors.toList());
            existRecord = this.list(Wrappers.<EamMouldEmailRecord>lambdaQuery()
                            .in(EamMouldEmailRecord::getAssetId, mouldIdList)
                            .eq(EamMouldEmailRecord::getDeleted, 0))
                    .stream()
                    .collect(Collectors.toMap(t -> t.getAssetId() + t.getProductId() + t.getSendStage(), Function.identity()));
        }
        Map<String, EamMouldEmailRecord> finalExistRecord = existRecord;
        // 查询配置下的所有用户
        List<String> roleIds = configList.stream().map(t -> Arrays.asList(t.getSendRoleId().split(","))).flatMap(Collection::stream).distinct().filter(StrUtil::isNotEmpty).collect(Collectors.toList());
        getPersonLogin();
        RetResult<List<SysUserWithRoleIdDTO>> userList = sysServiceFeign.getUserListByRoleIds(roleIds);
        Map<String, List<SysUserWithRoleIdDTO>> userMapByRole = new HashMap<>();
        if (userList != null && userList.getData() != null) {
            userMapByRole = userList.getData().stream().collect(Collectors.groupingBy(SysUserWithRoleIdDTO::getRoleId));
        }
        Map<String, List<SysUserWithRoleIdDTO>> finalUserMapByRole = userMapByRole;
        List<EamMouldEmailRecordDTO> records = mouldList.stream()
                .flatMap(mould ->
                                // 获取配置
                                configMap.get(mould.getProductId())
                                        .stream()
                                        // 配置根据阶段排序
                                        .sorted(Comparator.comparingInt(EamMouldEmailConfig::getSendStage))
                                        // 构建发送邮件记录
                                        .map(config -> {
                                            EamMouldEmailRecordDTO record = null;
                                            // 如果累计使用次数大于提醒数量
                                            if (mould.getCumulativeUseTimes() != null && mould.getCumulativeUseTimes() > config.getAlramQuantity()) {
                                                // 待确认 如果没查到邮箱  还构建发送记录么
                                                // 确认 如果没查到不保存记录
                                                List<SysUserWithRoleIdDTO> sysUserWithRoleIdDTOS = Arrays.stream(config.getSendRoleId().split(","))
                                                        .map(t -> finalUserMapByRole.getOrDefault(t, new ArrayList<>()))
                                                        .flatMap(Collection::stream)
                                                        .collect(Collectors.toList());
//                            List<SysUserWithRoleIdDTO> sysUserWithRoleIdDTOS = finalUserMapByRole.getOrDefault(config.getSendRoleId(), new ArrayList<>());
                                                List<String> emails = sysUserWithRoleIdDTOS.stream().map(SysUserDTO::getEmail).distinct().filter(StrUtil::isNotEmpty).collect(Collectors.toList());
//                                                if (CollUtil.isEmpty(emails)) return null;
                                                // 如果不存在发送记录  构建发送记录
                                                if (finalExistRecord.get(mould.getId() + config.getProductId() + config.getSendStage()) == null) {
                                                    String id = IdUtils.newId();
                                                    record = EamMouldEmailRecordDTO.builder()
                                                            .configId(config.getId())
                                                            .assetId(mould.getId())
                                                            .assetCode(mould.getAssetCode())
                                                            .assetName(mould.getAssetName())
                                                            .productId(config.getProductId())
                                                            .productCode(config.getProductCode())
                                                            .productName(config.getProductName())
                                                            .sendStage(config.getSendStage())
                                                            .locationId(mould.getLocationId())
                                                            .locationName(mould.getLocationName())
                                                            .assetTypeId(mould.getAssetTypeId())
                                                            .assetTypeCode(mould.getAssetTypeCode())
                                                            .assetTypeName(mould.getAssetTypeName())
                                                            .assetLifespan(mould.getAssetLifespan())
                                                            .cumulativeUseTimes(mould.getCumulativeUseTimes())
                                                            .registrationTime(new Date())
                                                            .details(sysUserWithRoleIdDTOS.stream()
                                                                    .filter(t -> StrUtil.isNotEmpty(t.getEmail()))
                                                                    .map(t -> EamMouldEmailRecordDetailDTO.builder()
                                                                            .recordId(id)
                                                                            .email(t.getEmail())
                                                                            .sendUserId(t.getId())
                                                                            .sendUserName(t.getFirstName())
                                                                            .sendTitle(config.getSendTitle())
                                                                            .sendContent(StrUtil.format("产品:{},模具:{},已使用次数:{},已到达阶段:{},提醒次数:{}",
                                                                                    config.getProductName(), mould.getAssetName(), mould.getCumulativeUseTimes(), config.getSendStage(), config.getAlramQuantity()))
                                                                            .build())
                                                                    .collect(Collectors.toList()))
                                                            .build()
                                                            .id(id);
                                                }
                                            }
                                            return record;
                                        })
                                        .filter(Objects::nonNull)
                )
                .collect(Collectors.toList());
        // 保存主子表
        if (CollUtil.isEmpty(records)) return;
        List<EamMouldEmailRecord> recordList = records.stream().map(record -> {
            EamMouldEmailRecord eamMouldEmailRecord = BeanUtil.copyProperties(record, EamMouldEmailRecord.class);
            this.setDefaultValue(eamMouldEmailRecord);
            return eamMouldEmailRecord;
        }).collect(Collectors.toList());
        this.saveBatch(recordList);
        List<EamMouldEmailRecordDetailDTO> details = records.stream().flatMap(record -> record.getDetails().stream()).collect(Collectors.toList());
        if (CollUtil.isEmpty(details)) return;
        eamMouldEmailRecordDetailService.saveBatch(details);
        // 发送邮件
        details.stream().collect(Collectors.groupingBy(EamMouldEmailRecordDetailDTO::getEmail))
                .forEach((emailAddress, value) -> {
                    String contents = value.stream().map(EamMouldEmailRecordDetailDTO::getSendContent).collect(Collectors.joining("<br/>"));
                    String titles = value.stream().map(EamMouldEmailRecordDetailDTO::getSendTitle).collect(Collectors.joining(","));
                    sendEmail(emailAddress, contents, titles);
                });

    }

    /**
     * 指定邮箱发送邮件
     *
     * @param email   邮箱
     * @param content 内容
     */
    private void sendEmail(String email, String content, String title) {
        if (StrUtil.isEmpty(email)) return;
        // 构建邮件
        Map<String, Object> stringObjectMap = new HashMap<>();

        stringObjectMap.put("content", content);
        SendMsgModel sendMsgModel = new SendMsgModel();
        List<String> msgType = new ArrayList<>();
        msgType.add("mouldLifeReminder");
        sendMsgModel.setMsgTypeCodeList(msgType);
        sendMsgModel.setContent(stringObjectMap);
        sendMsgModel.setTitle(title);

        sendMsgModel.setReceiveEmails(ListUtil.of(email));
        RetResult<?> send = sysMessageCenterServiceFeign.send(sendMsgModel);
        if (send == null || send.getData() == null) {
            throw new CustomException("邮件发送失败");
        }
        Map<String, List<String>> data = (Map<String, List<String>>) send.getData();
        if (CollUtil.isNotEmpty(data.get("errMsgTypeCodeList"))) {
            throw new CustomException("邮件发送失败");
        }
    }


    /**
     * 构造服务间调用token
     *
     * @return
     */
    public void getPersonLogin() {
        // 设置登录信息
        LoginInfo loginUser = new LoginInfo();
        loginUser.setUserId(userId);
        loginUser.setLoginName(userName);
        loginUser.setUserName(loginUserName);
        loginUser.setLoginTime(new Date());
        loginUser.getParameters().put("empNo", empNo);
        String token = tokenService.createLogin(loginUser);
        ApplicationContextHolder.set(SecurityConstants.AUTHORIZATION_KEY, token);
    }

    /**
     * 获取文件详情
     *
     * @param id
     * @return
     */
    public EamMouldEmailRecordDTO getDetail(String id) {
        EamMouldEmailRecordDTO eamMouldEmailRecordDTO = this.get(id);
        if (eamMouldEmailRecordDTO != null) {
            EamMouldEmailRecordFileQuery query = new EamMouldEmailRecordFileQuery();
            query.setEmailRecordId(id);
            List<EamMouldEmailRecordFileDTO> eamMouldEmailRecordFileDTOList = eamMouldEmailRecordFileService.getList(query);
            eamMouldEmailRecordDTO.setFiles(eamMouldEmailRecordFileDTOList);
        }
        return eamMouldEmailRecordDTO;
    }
}

